Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_hotspot
提交
20e010f6
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看板
提交
20e010f6
编写于
9月 12, 2018
作者:
C
coleenp
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
8210094: Better loading of classloader classes
Reviewed-by: acorn, hseigel, ahgross, rhalade
上级
2464089d
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
373 addition
and
68 deletion
+373
-68
src/share/vm/classfile/classFileParser.cpp
src/share/vm/classfile/classFileParser.cpp
+0
-27
src/share/vm/classfile/dictionary.cpp
src/share/vm/classfile/dictionary.cpp
+1
-25
src/share/vm/classfile/systemDictionary.cpp
src/share/vm/classfile/systemDictionary.cpp
+10
-1
src/share/vm/classfile/verificationType.cpp
src/share/vm/classfile/verificationType.cpp
+1
-3
src/share/vm/classfile/verifier.cpp
src/share/vm/classfile/verifier.cpp
+2
-4
src/share/vm/oops/constantPool.cpp
src/share/vm/oops/constantPool.cpp
+0
-2
src/share/vm/prims/jvm.cpp
src/share/vm/prims/jvm.cpp
+0
-6
test/runtime/ClassUnload/ConstantPoolDependsTest.java
test/runtime/ClassUnload/ConstantPoolDependsTest.java
+86
-0
test/runtime/ClassUnload/DictionaryDependsTest.java
test/runtime/ClassUnload/DictionaryDependsTest.java
+89
-0
test/runtime/ClassUnload/MyDiffClassLoader.java
test/runtime/ClassUnload/MyDiffClassLoader.java
+75
-0
test/runtime/ClassUnload/SuperDependsTest.java
test/runtime/ClassUnload/SuperDependsTest.java
+81
-0
test/runtime/ClassUnload/p2/c2.java
test/runtime/ClassUnload/p2/c2.java
+28
-0
未找到文件。
src/share/vm/classfile/classFileParser.cpp
浏览文件 @
20e010f6
...
@@ -4210,9 +4210,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
...
@@ -4210,9 +4210,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass
(),
&
all_mirandas
,
CHECK_
(
nullHandle
));
this_klass
(),
&
all_mirandas
,
CHECK_
(
nullHandle
));
}
}
// Update the loader_data graph.
record_defined_class_dependencies
(
this_klass
,
CHECK_NULL
);
ClassLoadingService
::
notify_class_loaded
(
InstanceKlass
::
cast
(
this_klass
()),
ClassLoadingService
::
notify_class_loaded
(
InstanceKlass
::
cast
(
this_klass
()),
false
/* not shared class */
);
false
/* not shared class */
);
...
@@ -4498,30 +4495,6 @@ void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
...
@@ -4498,30 +4495,6 @@ void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
}
}
}
}
// Attach super classes and interface classes to class loader data
void
ClassFileParser
::
record_defined_class_dependencies
(
instanceKlassHandle
defined_klass
,
TRAPS
)
{
ClassLoaderData
*
defining_loader_data
=
defined_klass
->
class_loader_data
();
if
(
defining_loader_data
->
is_the_null_class_loader_data
())
{
// Dependencies to null class loader data are implicit.
return
;
}
else
{
// add super class dependency
Klass
*
super
=
defined_klass
->
super
();
if
(
super
!=
NULL
)
{
defining_loader_data
->
record_dependency
(
super
,
CHECK
);
}
// add super interface dependencies
Array
<
Klass
*>*
local_interfaces
=
defined_klass
->
local_interfaces
();
if
(
local_interfaces
!=
NULL
)
{
int
length
=
local_interfaces
->
length
();
for
(
int
i
=
0
;
i
<
length
;
i
++
)
{
defining_loader_data
->
record_dependency
(
local_interfaces
->
at
(
i
),
CHECK
);
}
}
}
}
// utility methods for appending an array with check for duplicates
// utility methods for appending an array with check for duplicates
void
append_interfaces
(
GrowableArray
<
Klass
*>*
result
,
Array
<
Klass
*>*
ifs
)
{
void
append_interfaces
(
GrowableArray
<
Klass
*>*
result
,
Array
<
Klass
*>*
ifs
)
{
...
...
src/share/vm/classfile/dictionary.cpp
浏览文件 @
20e010f6
/*
/*
* Copyright (c) 2003, 201
6
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
8
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -159,33 +159,9 @@ void Dictionary::do_unloading() {
...
@@ -159,33 +159,9 @@ void Dictionary::do_unloading() {
if
(
!
is_strongly_reachable
(
loader_data
,
e
))
{
if
(
!
is_strongly_reachable
(
loader_data
,
e
))
{
// Entry was not visited in phase1 (negated test from phase1)
// Entry was not visited in phase1 (negated test from phase1)
assert
(
!
loader_data
->
is_the_null_class_loader_data
(),
"unloading entry with null class loader"
);
assert
(
!
loader_data
->
is_the_null_class_loader_data
(),
"unloading entry with null class loader"
);
ClassLoaderData
*
k_def_class_loader_data
=
ik
->
class_loader_data
();
// Do we need to delete this system dictionary entry?
bool
purge_entry
=
false
;
// Do we need to delete this system dictionary entry?
// Do we need to delete this system dictionary entry?
if
(
loader_data
->
is_unloading
())
{
if
(
loader_data
->
is_unloading
())
{
// If the loader is not live this entry should always be
// removed (will never be looked up again).
purge_entry
=
true
;
}
else
{
// The loader in this entry is alive. If the klass is dead,
// (determined by checking the defining class loader)
// the loader must be an initiating loader (rather than the
// defining loader). Remove this entry.
if
(
k_def_class_loader_data
->
is_unloading
())
{
// If we get here, the class_loader_data must not be the defining
// loader, it must be an initiating one.
assert
(
k_def_class_loader_data
!=
loader_data
,
"cannot have live defining loader and unreachable klass"
);
// Loader is live, but class and its defining loader are dead.
// Remove the entry. The class is going away.
purge_entry
=
true
;
}
}
if
(
purge_entry
)
{
*
p
=
probe
->
next
();
*
p
=
probe
->
next
();
if
(
probe
==
_current_class_entry
)
{
if
(
probe
==
_current_class_entry
)
{
_current_class_entry
=
NULL
;
_current_class_entry
=
NULL
;
...
...
src/share/vm/classfile/systemDictionary.cpp
浏览文件 @
20e010f6
...
@@ -816,7 +816,16 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
...
@@ -816,7 +816,16 @@ Klass* SystemDictionary::resolve_instance_class_or_null(Symbol* name,
check_constraints
(
d_index
,
d_hash
,
k
,
class_loader
,
false
,
THREAD
);
check_constraints
(
d_index
,
d_hash
,
k
,
class_loader
,
false
,
THREAD
);
// Need to check for a PENDING_EXCEPTION again; check_constraints
// Need to check for a PENDING_EXCEPTION again; check_constraints
// can throw and doesn't use the CHECK macro.
// can throw but we may have to remove entry from the placeholder table below.
if
(
!
HAS_PENDING_EXCEPTION
)
{
// Record dependency for non-parent delegation.
// This recording keeps the defining class loader of the klass (k) found
// from being unloaded while the initiating class loader is loaded
// even if the reference to the defining class loader is dropped
// before references to the initiating class loader.
loader_data
->
record_dependency
(
k
(),
THREAD
);
}
if
(
!
HAS_PENDING_EXCEPTION
)
{
if
(
!
HAS_PENDING_EXCEPTION
)
{
{
// Grabbing the Compile_lock prevents systemDictionary updates
{
// Grabbing the Compile_lock prevents systemDictionary updates
// during compilations.
// during compilations.
...
...
src/share/vm/classfile/verificationType.cpp
浏览文件 @
20e010f6
/*
/*
* Copyright (c) 2003, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 201
8
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -63,7 +63,6 @@ bool VerificationType::is_reference_assignable_from(
...
@@ -63,7 +63,6 @@ bool VerificationType::is_reference_assignable_from(
name
(),
Handle
(
THREAD
,
klass
->
class_loader
()),
name
(),
Handle
(
THREAD
,
klass
->
class_loader
()),
Handle
(
THREAD
,
klass
->
protection_domain
()),
true
,
CHECK_false
);
Handle
(
THREAD
,
klass
->
protection_domain
()),
true
,
CHECK_false
);
KlassHandle
this_class
(
THREAD
,
obj
);
KlassHandle
this_class
(
THREAD
,
obj
);
klass
->
class_loader_data
()
->
record_dependency
(
obj
,
CHECK_false
);
if
(
this_class
->
is_interface
()
&&
(
!
from_field_is_protected
||
if
(
this_class
->
is_interface
()
&&
(
!
from_field_is_protected
||
from
.
name
()
!=
vmSymbols
::
java_lang_Object
()))
{
from
.
name
()
!=
vmSymbols
::
java_lang_Object
()))
{
...
@@ -75,7 +74,6 @@ bool VerificationType::is_reference_assignable_from(
...
@@ -75,7 +74,6 @@ bool VerificationType::is_reference_assignable_from(
Klass
*
from_class
=
SystemDictionary
::
resolve_or_fail
(
Klass
*
from_class
=
SystemDictionary
::
resolve_or_fail
(
from
.
name
(),
Handle
(
THREAD
,
klass
->
class_loader
()),
from
.
name
(),
Handle
(
THREAD
,
klass
->
class_loader
()),
Handle
(
THREAD
,
klass
->
protection_domain
()),
true
,
CHECK_false
);
Handle
(
THREAD
,
klass
->
protection_domain
()),
true
,
CHECK_false
);
klass
->
class_loader_data
()
->
record_dependency
(
from_class
,
CHECK_false
);
bool
result
=
InstanceKlass
::
cast
(
from_class
)
->
is_subclass_of
(
this_class
());
bool
result
=
InstanceKlass
::
cast
(
from_class
)
->
is_subclass_of
(
this_class
());
if
(
result
&&
DumpSharedSpaces
)
{
if
(
result
&&
DumpSharedSpaces
)
{
if
(
klass
()
->
is_subclass_of
(
from_class
)
&&
klass
()
->
is_subclass_of
(
this_class
()))
{
if
(
klass
()
->
is_subclass_of
(
from_class
)
&&
klass
()
->
is_subclass_of
(
this_class
()))
{
...
...
src/share/vm/classfile/verifier.cpp
浏览文件 @
20e010f6
/*
/*
* Copyright (c) 1998, 201
7
, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1998, 201
8
, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
*
* This code is free software; you can redistribute it and/or modify it
* This code is free software; you can redistribute it and/or modify it
...
@@ -1949,11 +1949,9 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
...
@@ -1949,11 +1949,9 @@ Klass* ClassVerifier::load_class(Symbol* name, TRAPS) {
oop
loader
=
current_class
()
->
class_loader
();
oop
loader
=
current_class
()
->
class_loader
();
oop
protection_domain
=
current_class
()
->
protection_domain
();
oop
protection_domain
=
current_class
()
->
protection_domain
();
Klass
*
kls
=
SystemDictionary
::
resolve_or_fail
(
return
SystemDictionary
::
resolve_or_fail
(
name
,
Handle
(
THREAD
,
loader
),
Handle
(
THREAD
,
protection_domain
),
name
,
Handle
(
THREAD
,
loader
),
Handle
(
THREAD
,
protection_domain
),
true
,
CHECK_NULL
);
true
,
CHECK_NULL
);
current_class
()
->
class_loader_data
()
->
record_dependency
(
kls
,
CHECK_NULL
);
return
kls
;
}
}
bool
ClassVerifier
::
is_protected_access
(
instanceKlassHandle
this_class
,
bool
ClassVerifier
::
is_protected_access
(
instanceKlassHandle
this_class
,
...
...
src/share/vm/oops/constantPool.cpp
浏览文件 @
20e010f6
...
@@ -339,8 +339,6 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
...
@@ -339,8 +339,6 @@ Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS
// Only updated constant pool - if it is resolved.
// Only updated constant pool - if it is resolved.
do_resolve
=
this_oop
->
tag_at
(
which
).
is_unresolved_klass
();
do_resolve
=
this_oop
->
tag_at
(
which
).
is_unresolved_klass
();
if
(
do_resolve
)
{
if
(
do_resolve
)
{
ClassLoaderData
*
this_key
=
this_oop
->
pool_holder
()
->
class_loader_data
();
this_key
->
record_dependency
(
k
(),
CHECK_NULL
);
// Can throw OOM
this_oop
->
klass_at_put
(
which
,
k
());
this_oop
->
klass_at_put
(
which
,
k
());
}
}
}
}
...
...
src/share/vm/prims/jvm.cpp
浏览文件 @
20e010f6
...
@@ -991,12 +991,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
...
@@ -991,12 +991,6 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name,
Handle
h_prot
(
THREAD
,
protection_domain
);
Handle
h_prot
(
THREAD
,
protection_domain
);
jclass
result
=
find_class_from_class_loader
(
env
,
h_name
,
init
,
h_loader
,
jclass
result
=
find_class_from_class_loader
(
env
,
h_name
,
init
,
h_loader
,
h_prot
,
true
,
thread
);
h_prot
,
true
,
thread
);
if
(
result
!=
NULL
)
{
oop
mirror
=
JNIHandles
::
resolve_non_null
(
result
);
Klass
*
to_class
=
java_lang_Class
::
as_Klass
(
mirror
);
ClassLoaderData
*
cld
=
ClassLoaderData
::
class_loader_data
(
h_loader
());
cld
->
record_dependency
(
to_class
,
CHECK_NULL
);
}
if
(
TraceClassResolution
&&
result
!=
NULL
)
{
if
(
TraceClassResolution
&&
result
!=
NULL
)
{
// this function is generally only used for class loading during verification.
// this function is generally only used for class loading during verification.
...
...
test/runtime/ClassUnload/ConstantPoolDependsTest.java
0 → 100644
浏览文件 @
20e010f6
/*
* Copyright (c) 2018, 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.
*/
/*
* @test ConstantPoolDependsTest
* @bug 8210094
* @summary Create ClassLoader dependency from initiating loader to class loader through constant pool reference
* @modules java.base/jdk.internal.misc
* java.compiler
* @library /testlibrary /testlibrary/whitebox /runtime/testlibrary
* @build sun.hotspot.WhiteBox
* @compile p2/c2.java MyDiffClassLoader.java
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ConstantPoolDependsTest
*/
import
sun.hotspot.WhiteBox
;
public
class
ConstantPoolDependsTest
{
public
static
WhiteBox
wb
=
WhiteBox
.
getWhiteBox
();
public
static
final
String
MY_TEST
=
"ConstantPoolDependsTest$c1c"
;
public
static
class
c1c
{
private
void
test
()
throws
Exception
{
// ConstantPool.klass_at_impl loads through constant pool and creates dependency
p2
.
c2
c2_obj
=
new
p2
.
c2
();
c2_obj
.
method2
();
}
public
c1c
()
throws
Exception
{
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
}
}
static
void
test
()
throws
Throwable
{
// now use the same loader to load class MyTest
Class
MyTest_class
=
new
MyDiffClassLoader
(
MY_TEST
).
loadClass
(
MY_TEST
);
try
{
// Call MyTest to load p2.c2 twice and call p2.c2.method2
MyTest_class
.
newInstance
();
}
catch
(
Exception
e
)
{
throw
new
RuntimeException
(
"Test FAILED if NoSuchMethodException is thrown"
);
}
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
MY_TEST
),
"should not be unloaded"
);
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
"p2.c2"
),
"should not be unloaded"
);
// Unless MyTest_class is referenced here, the compiler can unload it.
System
.
out
.
println
(
"Should not unload anything before here because "
+
MyTest_class
+
" is still alive."
);
}
public
static
void
main
(
String
args
[])
throws
Throwable
{
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should unload
System
.
gc
();
System
.
out
.
println
(
"Should unload p2.c2 just now"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
MY_TEST
),
"should be unloaded"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
"p2.c2"
),
"should be unloaded"
);
}
}
test/runtime/ClassUnload/DictionaryDependsTest.java
0 → 100644
浏览文件 @
20e010f6
/*
* Copyright (c) 2018, 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.
*/
/*
* @test DictionaryDependsTest
* @bug 8210094
* @summary Create ClassLoader dependency from initiating loader to class loader through reflection
* @modules java.base/jdk.internal.misc
* java.compiler
* @library /testlibrary /testlibrary/whitebox /runtime/testlibrary
* @build sun.hotspot.WhiteBox
* @compile p2/c2.java MyDiffClassLoader.java
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI DictionaryDependsTest
*/
import
sun.hotspot.WhiteBox
;
import
java.lang.reflect.Method
;
public
class
DictionaryDependsTest
{
public
static
WhiteBox
wb
=
WhiteBox
.
getWhiteBox
();
public
static
final
String
MY_TEST
=
"DictionaryDependsTest$c1r"
;
static
public
class
c1r
{
private
void
test
()
throws
Exception
{
// forName loads through reflection and doesn't create dependency
Class
<?>
x
=
Class
.
forName
(
"p2.c2"
,
true
,
c1r
.
class
.
getClassLoader
());
Method
m
=
x
.
getMethod
(
"method2"
);
java
.
lang
.
Object
t
=
x
.
newInstance
();
m
.
invoke
(
t
);
}
public
c1r
()
throws
Exception
{
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should unload p2.c2
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should unload p2.c2
}
}
public
void
test
()
throws
Throwable
{
// now use the same loader to load class MyTest
Class
MyTest_class
=
new
MyDiffClassLoader
(
MY_TEST
).
loadClass
(
MY_TEST
);
try
{
// Call MyTest to load p2.c2 twice and call p2.c2.method2
MyTest_class
.
newInstance
();
}
catch
(
Exception
e
)
{
System
.
out
.
println
(
"Not expected NSME"
);
throw
new
RuntimeException
(
"Not expecting NSME"
);
}
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
MY_TEST
),
"should not be unloaded"
);
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
"p2.c2"
),
"should not be unloaded"
);
// Unless MyTest_class is referenced here, the compiler can unload it.
System
.
out
.
println
(
"Should not unload anything before here because "
+
MyTest_class
+
" is still alive."
);
}
public
static
void
main
(
String
args
[])
throws
Throwable
{
DictionaryDependsTest
d
=
new
DictionaryDependsTest
();
d
.
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
System
.
out
.
println
(
"Should unload MyTest and p2.c2 just now"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
MY_TEST
),
"should be unloaded"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
"p2.c2"
),
"should be unloaded"
);
}
}
test/runtime/ClassUnload/MyDiffClassLoader.java
0 → 100644
浏览文件 @
20e010f6
/*
* Copyright (c) 2018, 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.
*/
import
java.io.*
;
import
com.oracle.java.testlibrary.InMemoryJavaCompiler
;
public
class
MyDiffClassLoader
extends
ClassLoader
{
public
String
loaderName
;
public
static
boolean
switchClassData
=
false
;
MyDiffClassLoader
(
String
name
)
{
this
.
loaderName
=
name
;
}
public
Class
loadClass
(
String
name
)
throws
ClassNotFoundException
{
if
(!
name
.
contains
(
"c1r"
)
&&
!
name
.
contains
(
"c1c"
)
&&
!
name
.
contains
(
"c1s"
)
&&
!
name
.
equals
(
"p2.c2"
))
{
return
super
.
loadClass
(
name
);
}
// new loader loads p2.c2
if
(
name
.
equals
(
"p2.c2"
)
&&
!
loaderName
.
equals
(
"C2Loader"
))
{
Class
<?>
c
=
new
MyDiffClassLoader
(
"C2Loader"
).
loadClass
(
name
);
switchClassData
=
true
;
return
c
;
}
byte
[]
data
=
switchClassData
?
getNewClassData
(
name
)
:
getClassData
(
name
);
System
.
out
.
println
(
"name is "
+
name
);
return
defineClass
(
name
,
data
,
0
,
data
.
length
);
}
byte
[]
getClassData
(
String
name
)
{
try
{
String
TempName
=
name
.
replaceAll
(
"\\."
,
"/"
);
String
currentDir
=
System
.
getProperty
(
"test.classes"
);
String
filename
=
currentDir
+
File
.
separator
+
TempName
+
".class"
;
FileInputStream
fis
=
new
FileInputStream
(
filename
);
byte
[]
b
=
new
byte
[
5000
];
int
cnt
=
fis
.
read
(
b
,
0
,
5000
);
byte
[]
c
=
new
byte
[
cnt
];
for
(
int
i
=
0
;
i
<
cnt
;
i
++)
c
[
i
]
=
b
[
i
];
return
c
;
}
catch
(
IOException
e
)
{
return
null
;
}
}
// Return p2.c2 with everything removed
byte
[]
getNewClassData
(
String
name
)
{
return
InMemoryJavaCompiler
.
compile
(
"p2.c2"
,
"package p2; public class c2 { }"
);
}
}
test/runtime/ClassUnload/SuperDependsTest.java
0 → 100644
浏览文件 @
20e010f6
/*
* Copyright (c) 2018, 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.
*/
/*
* @test SuperDependsTest
* @bug 8210094
* @summary Create ClassLoader dependency from initiating loader to class loader through subclassing
* @modules java.base/jdk.internal.misc
* java.compiler
* @library /testlibrary /testlibrary/whitebox /runtime/testlibrary
* @build sun.hotspot.WhiteBox
* @compile p2/c2.java MyDiffClassLoader.java
* @run main ClassFileInstaller sun.hotspot.WhiteBox
* sun.hotspot.WhiteBox$WhiteBoxPermission
* @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI SuperDependsTest
*/
import
sun.hotspot.WhiteBox
;
import
p2.*
;
public
class
SuperDependsTest
{
public
static
WhiteBox
wb
=
WhiteBox
.
getWhiteBox
();
public
static
final
String
MY_TEST
=
"SuperDependsTest$c1s"
;
// p2.c2 loads through super class and creates dependency
public
static
class
c1s
extends
p2
.
c2
{
private
void
test
()
throws
Exception
{
method2
();
}
public
c1s
()
throws
Exception
{
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
test
();
}
}
public
void
test
()
throws
Throwable
{
// now use the same loader to load class MyTest
Class
MyTest_class
=
new
MyDiffClassLoader
(
MY_TEST
).
loadClass
(
MY_TEST
);
// Call MyTest to load p2.c2 twice and call p2.c2.method2
MyTest_class
.
newInstance
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
MY_TEST
),
"should not be unloaded"
);
ClassUnloadCommon
.
failIf
(!
wb
.
isClassAlive
(
"p2.c2"
),
"should not be unloaded"
);
// Unless MyTest_class is referenced here, the compiler can unload it.
System
.
out
.
println
(
"Should not unload anything before here because "
+
MyTest_class
+
" is still alive."
);
}
public
static
void
main
(
String
args
[])
throws
Throwable
{
SuperDependsTest
d
=
new
SuperDependsTest
();
d
.
test
();
ClassUnloadCommon
.
triggerUnloading
();
// should not unload anything
System
.
out
.
println
(
"Should unload MyTest and p2.c2 just now"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
MY_TEST
),
"should be unloaded"
);
ClassUnloadCommon
.
failIf
(
wb
.
isClassAlive
(
"p2.c2"
),
"should be unloaded"
);
}
}
test/runtime/ClassUnload/p2/c2.java
0 → 100644
浏览文件 @
20e010f6
/*
* Copyright (c) 2018, 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.
*/
package
p2
;
public
class
c2
{
int
i
;
public
void
method2
()
{
i
=
5
;
System
.
out
.
println
(
"c2 method2 called"
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录