8213211: [BACKOUT] Allow Klass::_subklass and _next_sibling to have unloaded classes
Reviewed-by: jiangli, jwilhelm
--- a/src/hotspot/share/ci/ciInstanceKlass.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/ci/ciInstanceKlass.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -57,7 +57,7 @@
AccessFlags access_flags = ik->access_flags();
_flags = ciFlags(access_flags);
_has_finalizer = access_flags.has_finalizer();
- _has_subklass = flags().is_final() ? subklass_false : subklass_unknown;
+ _has_subklass = ik->subklass() != NULL;
_init_state = ik->init_state();
_nonstatic_field_size = ik->nonstatic_field_size();
_has_nonstatic_fields = ik->has_nonstatic_fields();
@@ -146,10 +146,9 @@
// ciInstanceKlass::compute_shared_has_subklass
bool ciInstanceKlass::compute_shared_has_subklass() {
GUARDED_VM_ENTRY(
- MutexLocker ml(Compile_lock);
InstanceKlass* ik = get_instanceKlass();
- _has_subklass = ik->subklass() != NULL ? subklass_true : subklass_false;
- return _has_subklass == subklass_true;
+ _has_subklass = ik->subklass() != NULL;
+ return _has_subklass;
)
}
@@ -375,7 +374,6 @@
if (!is_abstract()) return NULL; // Only applies to abstract classes.
if (!has_subklass()) return NULL; // Must have at least one subklass.
VM_ENTRY_MARK;
- MutexLocker ml(Compile_lock);
InstanceKlass* ik = get_instanceKlass();
Klass* up = ik->up_cast_abstract();
assert(up->is_instance_klass(), "must be InstanceKlass");
@@ -390,7 +388,6 @@
bool ciInstanceKlass::has_finalizable_subclass() {
if (!is_loaded()) return true;
VM_ENTRY_MARK;
- MutexLocker ml(Compile_lock);
return Dependencies::find_finalizable_subclass(get_instanceKlass()) != NULL;
}
@@ -580,7 +577,7 @@
if (is_shared()) {
return is_final(); // approximately correct
} else {
- return !has_subklass() && (nof_implementors() == 0);
+ return !_has_subklass && (nof_implementors() == 0);
}
}
--- a/src/hotspot/share/ci/ciInstanceKlass.hpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/ci/ciInstanceKlass.hpp Wed Oct 31 14:38:14 2018 -0400
@@ -44,15 +44,13 @@
friend class ciField;
private:
- enum SubklassValue { subklass_unknown, subklass_false, subklass_true };
-
jobject _loader;
jobject _protection_domain;
InstanceKlass::ClassState _init_state; // state of class
bool _is_shared;
bool _has_finalizer;
- SubklassValue _has_subklass;
+ bool _has_subklass;
bool _has_nonstatic_fields;
bool _has_nonstatic_concrete_methods;
bool _is_unsafe_anonymous;
@@ -141,15 +139,14 @@
return _has_finalizer; }
bool has_subklass() {
assert(is_loaded(), "must be loaded");
- if (_has_subklass == subklass_unknown ||
- (_is_shared && _has_subklass == subklass_false)) {
+ if (_is_shared && !_has_subklass) {
if (flags().is_final()) {
return false;
} else {
return compute_shared_has_subklass();
}
}
- return _has_subklass == subklass_true;
+ return _has_subklass;
}
jint size_helper() {
return (Klass::layout_helper_size_in_bytes(layout_helper())
--- a/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/jfr/jni/jfrGetAllEventClasses.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -90,6 +90,7 @@
DEBUG_ONLY(JfrJavaSupport::check_java_thread_in_vm(thread));
Stack<const Klass*, mtTracing> mark_stack;
+ MutexLocker ml(Compile_lock, thread);
mark_stack.push(event_klass->subklass());
while (!mark_stack.is_empty()) {
@@ -145,19 +146,16 @@
assert(klass != NULL, "invariant");
assert(JdkJfrEvent::is(klass), "invariant");
+ if (klass->subklass() == NULL) {
+ return empty_java_util_arraylist;
+ }
+
ResourceMark rm(THREAD);
GrowableArray<const void*> event_subklasses(THREAD, initial_size_growable_array);
- {
- MutexLocker cl(Compile_lock);
- if (klass->subklass() == NULL) {
- return empty_java_util_arraylist;
- }
+ fill_klasses(event_subklasses, klass, THREAD);
- fill_klasses(event_subklasses, klass, THREAD);
-
- if (event_subklasses.is_empty()) {
- return empty_java_util_arraylist;
- }
+ if (event_subklasses.is_empty()) {
+ return empty_java_util_arraylist;
}
transform_klasses_to_local_jni_handles(event_subklasses, THREAD);
--- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -627,7 +627,6 @@
C2V_VMENTRY(jboolean, hasFinalizableSubclass,(JNIEnv *, jobject, jobject jvmci_type))
Klass* klass = CompilerToVM::asKlass(jvmci_type);
assert(klass != NULL, "method must not be called for primitive types");
- MutexLocker ml(Compile_lock);
return Dependencies::find_finalizable_subclass(klass) != NULL;
C2V_END
--- a/src/hotspot/share/memory/universe.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/memory/universe.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -531,6 +531,10 @@
#undef assert_pll_locked
#undef assert_pll_ownership
+// initialize_vtable could cause gc if
+// 1) we specified true to initialize_vtable and
+// 2) this ran after gc was enabled
+// In case those ever change we use handles for oops
void Universe::reinitialize_vtable_of(Klass* ko, TRAPS) {
// init vtable of k and all subclasses
ko->vtable().initialize_vtable(false, CHECK);
@@ -543,16 +547,6 @@
}
}
-void Universe::reinitialize_vtables(TRAPS) {
- // The vtables are initialized by starting at java.lang.Object and
- // initializing through the subclass links, so that the super
- // classes are always initialized first. The subclass links
- // require the Compile_lock.
- MutexLocker cl(Compile_lock);
- Klass* ok = SystemDictionary::Object_klass();
- Universe::reinitialize_vtable_of(ok, THREAD);
-}
-
void initialize_itable_for_klass(InstanceKlass* k, TRAPS) {
k->itable().initialize_itable(false, CHECK);
@@ -970,7 +964,9 @@
{ ResourceMark rm;
Interpreter::initialize(); // needed for interpreter entry points
if (!UseSharedSpaces) {
- Universe::reinitialize_vtables(CHECK_false);
+ HandleMark hm(THREAD);
+ Klass* ok = SystemDictionary::Object_klass();
+ Universe::reinitialize_vtable_of(ok, CHECK_false);
Universe::reinitialize_itables(CHECK_false);
}
}
--- a/src/hotspot/share/memory/universe.hpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/memory/universe.hpp Wed Oct 31 14:38:14 2018 -0400
@@ -219,7 +219,6 @@
static void fixup_mirrors(TRAPS);
static void reinitialize_vtable_of(Klass* k, TRAPS);
- static void reinitialize_vtables(TRAPS);
static void reinitialize_itables(TRAPS);
static void compute_base_vtable_size(); // compute vtable size of class Object
--- a/src/hotspot/share/oops/instanceKlass.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -1054,28 +1054,16 @@
}
}
-Klass* InstanceKlass::implementor(bool log) const {
+Klass* InstanceKlass::implementor() const {
assert_locked_or_safepoint(Compile_lock);
Klass** k = adr_implementor();
if (k == NULL) {
return NULL;
} else {
- Klass* kls = *k;
- if (kls != NULL && !kls->is_loader_alive()) {
- if (log) {
- if (log_is_enabled(Trace, class, unload)) {
- ResourceMark rm;
- log_trace(class, unload)("unlinking class (implementor): %s", kls->external_name());
- }
- }
- return NULL; // don't return unloaded class
- } else {
- return kls;
- }
+ return *k;
}
}
-
void InstanceKlass::set_implementor(Klass* k) {
assert_lock_strong(Compile_lock);
assert(is_interface(), "not interface");
@@ -2151,15 +2139,20 @@
}
void InstanceKlass::clean_implementors_list() {
- assert_locked_or_safepoint(Compile_lock);
assert(is_loader_alive(), "this klass should be live");
if (is_interface()) {
- assert (ClassUnloading, "only called for ClassUnloading");
- Klass* impl = implementor(true);
- if (impl == NULL) {
- // NULL this field, might be an unloaded klass or NULL
- Klass** klass = adr_implementor();
- *klass = NULL;
+ if (ClassUnloading) {
+ Klass* impl = implementor();
+ if (impl != NULL) {
+ if (!impl->is_loader_alive()) {
+ // remove this guy
+ Klass** klass = adr_implementor();
+ assert(klass != NULL, "null klass");
+ if (klass != NULL) {
+ *klass = NULL;
+ }
+ }
+ }
}
}
}
@@ -3087,29 +3080,28 @@
st->print(BULLET"name: "); name()->print_value_on(st); st->cr();
st->print(BULLET"super: "); Metadata::print_value_on_maybe_null(st, super()); st->cr();
st->print(BULLET"sub: ");
- {
- MutexLocker ml(Compile_lock);
- Klass* sub = subklass();
- int n;
- for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) {
- if (n < MaxSubklassPrintSize) {
- sub->print_value_on(st);
- st->print(" ");
- }
- }
- if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize);
- st->cr();
-
- if (is_interface()) {
- st->print_cr(BULLET"nof implementors: %d", nof_implementors());
- if (nof_implementors() == 1) {
- st->print_cr(BULLET"implementor: ");
- st->print(" ");
- implementor()->print_value_on(st);
- st->cr();
- }
+ Klass* sub = subklass();
+ int n;
+ for (n = 0; sub != NULL; n++, sub = sub->next_sibling()) {
+ if (n < MaxSubklassPrintSize) {
+ sub->print_value_on(st);
+ st->print(" ");
}
}
+ if (n >= MaxSubklassPrintSize) st->print("(" INTX_FORMAT " more klasses...)", n - MaxSubklassPrintSize);
+ st->cr();
+
+ if (is_interface()) {
+ MutexLocker ml(Compile_lock);
+ st->print_cr(BULLET"nof implementors: %d", nof_implementors());
+ if (nof_implementors() == 1) {
+ st->print_cr(BULLET"implementor: ");
+ st->print(" ");
+ implementor()->print_value_on(st);
+ st->cr();
+ }
+ }
+
st->print(BULLET"arrays: "); Metadata::print_value_on_maybe_null(st, array_klasses()); st->cr();
st->print(BULLET"methods: "); methods()->print_value_on(st); st->cr();
if (Verbose || WizardMode) {
@@ -3491,30 +3483,26 @@
vtable().verify(st);
}
- // This is called from add_to_hierarchy when the Compile_lock is owned.
- {
- MutexLockerEx ml(Compile_lock->owned_by_self() ? NULL : Compile_lock);
- // Verify first subklass
- if (subklass() != NULL) {
- guarantee(subklass()->is_klass(), "should be klass");
+ // Verify first subklass
+ if (subklass() != NULL) {
+ guarantee(subklass()->is_klass(), "should be klass");
+ }
+
+ // Verify siblings
+ Klass* super = this->super();
+ Klass* sib = next_sibling();
+ if (sib != NULL) {
+ if (sib == this) {
+ fatal("subclass points to itself " PTR_FORMAT, p2i(sib));
}
- // Verify siblings
- Klass* super = this->super();
- Klass* sib = next_sibling();
- if (sib != NULL) {
- if (sib == this) {
- fatal("subclass points to itself " PTR_FORMAT, p2i(sib));
- }
-
- guarantee(sib->is_klass(), "should be klass");
- guarantee(sib->super() == super, "siblings should have same superklass");
- }
-
- // Verify implementor fields requires the Compile_lock,
- // but this is sometimes called inside a safepoint, so don't verify.
+ guarantee(sib->is_klass(), "should be klass");
+ guarantee(sib->super() == super, "siblings should have same superklass");
}
+ // Verify implementor fields requires the Compile_lock, but this is sometimes
+ // called inside a safepoint, so don't verify.
+
// Verify local interfaces
if (local_interfaces()) {
Array<InstanceKlass*>* local_interfaces = this->local_interfaces();
--- a/src/hotspot/share/oops/instanceKlass.hpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/oops/instanceKlass.hpp Wed Oct 31 14:38:14 2018 -0400
@@ -1007,7 +1007,7 @@
#endif
// Access to the implementor of an interface.
- Klass* implementor(bool log = false) const;
+ Klass* implementor() const;
void set_implementor(Klass* k);
int nof_implementors() const;
void add_implementor(Klass* k); // k is a new class that implements this interface
--- a/src/hotspot/share/oops/klass.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/oops/klass.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -117,7 +117,7 @@
Klass *r = this;
while( r->is_abstract() ) { // Receiver is abstract?
Klass *s = r->subklass(); // Check for exactly 1 subklass
- if (s == NULL || s->next_sibling() != NULL) // Oops; wrong count; give up
+ if( !s || s->next_sibling() ) // Oops; wrong count; give up
return this; // Return 'this' as a no-progress flag
r = s; // Loop till find concrete class
}
@@ -358,49 +358,11 @@
}
-// superklass links
InstanceKlass* Klass::superklass() const {
assert(super() == NULL || super()->is_instance_klass(), "must be instance klass");
return _super == NULL ? NULL : InstanceKlass::cast(_super);
}
-// subklass links. Used by the compiler (and vtable initialization)
-// May be cleaned concurrently, so must use the Compile_lock.
-// The log parameter is for clean_weak_klass_links to report unlinked classes.
-Klass* Klass::subklass(bool log) const {
- assert_locked_or_safepoint(Compile_lock);
- for (Klass* chain = _subklass; chain != NULL;
- chain = chain->_next_sibling) {
- if (chain->is_loader_alive()) {
- return chain;
- } else if (log) {
- if (log_is_enabled(Trace, class, unload)) {
- ResourceMark rm;
- log_trace(class, unload)("unlinking class (subclass): %s", chain->external_name());
- }
- }
- }
- return NULL;
-}
-
-Klass* Klass::next_sibling(bool log) const {
- assert_locked_or_safepoint(Compile_lock);
- for (Klass* chain = _next_sibling; chain != NULL;
- chain = chain->_next_sibling) {
- // Only return alive klass, there may be stale klass
- // in this chain if cleaned concurrently.
- if (chain->is_loader_alive()) {
- return chain;
- } else if (log) {
- if (log_is_enabled(Trace, class, unload)) {
- ResourceMark rm;
- log_trace(class, unload)("unlinking class (sibling): %s", chain->external_name());
- }
- }
- }
- return NULL;
-}
-
void Klass::set_subklass(Klass* s) {
assert(s != this, "sanity check");
_subklass = s;
@@ -412,7 +374,6 @@
}
void Klass::append_to_sibling_list() {
- assert_locked_or_safepoint(Compile_lock);
debug_only(verify();)
// add ourselves to superklass' subklass list
InstanceKlass* super = superklass();
@@ -420,7 +381,6 @@
assert((!super->is_interface() // interfaces cannot be supers
&& (super->superklass() == NULL || !is_interface())),
"an interface can only be a subklass of Object");
-
Klass* prev_first_subklass = super->subklass();
if (prev_first_subklass != NULL) {
// set our sibling to be the superklass' previous first subklass
@@ -436,7 +396,6 @@
}
void Klass::clean_weak_klass_links(bool unloading_occurred, bool clean_alive_klasses) {
- assert_locked_or_safepoint(Compile_lock);
if (!ClassUnloading || !unloading_occurred) {
return;
}
@@ -451,14 +410,30 @@
assert(current->is_loader_alive(), "just checking, this should be live");
// Find and set the first alive subklass
- Klass* sub = current->subklass(true);
+ Klass* sub = current->subklass();
+ while (sub != NULL && !sub->is_loader_alive()) {
+#ifndef PRODUCT
+ if (log_is_enabled(Trace, class, unload)) {
+ ResourceMark rm;
+ log_trace(class, unload)("unlinking class (subclass): %s", sub->external_name());
+ }
+#endif
+ sub = sub->next_sibling();
+ }
current->set_subklass(sub);
if (sub != NULL) {
stack.push(sub);
}
// Find and set the first alive sibling
- Klass* sibling = current->next_sibling(true);
+ Klass* sibling = current->next_sibling();
+ while (sibling != NULL && !sibling->is_loader_alive()) {
+ if (log_is_enabled(Trace, class, unload)) {
+ ResourceMark rm;
+ log_trace(class, unload)("[Unlinking class (sibling) %s]", sibling->external_name());
+ }
+ sibling = sibling->next_sibling();
+ }
current->set_next_sibling(sibling);
if (sibling != NULL) {
stack.push(sibling);
--- a/src/hotspot/share/oops/klass.hpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/oops/klass.hpp Wed Oct 31 14:38:14 2018 -0400
@@ -284,9 +284,8 @@
// Use InstanceKlass::contains_field_offset to classify field offsets.
// sub/superklass links
- Klass* subklass(bool log = false) const;
- Klass* next_sibling(bool log = false) const;
-
+ Klass* subklass() const { return _subklass; }
+ Klass* next_sibling() const { return _next_sibling; }
InstanceKlass* superklass() const;
void append_to_sibling_list(); // add newly created receiver to superklass' subklass list
--- a/src/hotspot/share/runtime/mutex.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/runtime/mutex.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -876,7 +876,7 @@
#endif // CHECK_UNHANDLED_OOPS
debug_only(check_prelock_state(Self, StrictSafepointChecks));
- assert(_owner != Self, "this lock %s is already held by this thread", name());
+ assert(_owner != Self, "invariant");
assert(_OnDeck != Self->_MutexEvent, "invariant");
if (TryFast()) {
--- a/src/hotspot/share/utilities/vmError.cpp Tue Oct 16 16:26:28 2018 -0400
+++ b/src/hotspot/share/utilities/vmError.cpp Wed Oct 31 14:38:14 2018 -0400
@@ -1467,8 +1467,6 @@
log.set_fd(-1);
}
- // Error handling generates replay data without the compile lock.
- NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true));
static bool skip_replay = ReplayCompiles; // Do not overwrite file during replay
if (DumpReplayDataOnError && _thread && _thread->is_Compiler_thread() && !skip_replay) {
skip_replay = true;
--- a/test/hotspot/jtreg/runtime/ClassUnload/UnloadInterfaceTest.java Tue Oct 16 16:26:28 2018 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,95 +0,0 @@
-/*
- * 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 UnloadInterfaceTest
- * @requires vm.opt.final.ClassUnloading
- * @modules java.base/jdk.internal.misc
- * @library /runtime/testlibrary /test/lib
- * @compile test/Interface.java
- * @compile test/ImplementorClass.java
- * @build sun.hotspot.WhiteBox
- * @run driver ClassFileInstaller sun.hotspot.WhiteBox
- * sun.hotspot.WhiteBox$WhiteBoxPermission
- * @run main/othervm -Xbootclasspath/a:. -Xmn8m -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xlog:class+unload=trace UnloadInterfaceTest
- */
-import sun.hotspot.WhiteBox;
-import test.Interface;
-import java.lang.ClassLoader;
-
-/**
- * Test that verifies that class unloaded removes the implementor from its the interface that it implements
- * via logging.
- * [1.364s][info][class,unload] unloading class test.ImplementorClass 0x00000008000a2840
- * [1.366s][trace][class,unload] unlinking class (subclass): test.ImplementorClass
- * [1.366s][trace][class,unload] unlinking class (implementor): test.ImplementorClass
- */
-public class UnloadInterfaceTest {
- private static String className = "test.ImplementorClass";
- private static String interfaceName = "test.Interface";
-
- static class LoaderToUnload extends ClassLoader {
- ClassLoader myParent;
- public Class loadClass(String name) throws ClassNotFoundException {
- if (name.contains(className)) {
- System.out.println("className found " + className);
- byte[] data = ClassUnloadCommon.getClassData(name);
- return defineClass(name, data, 0, data.length);
- } else {
- return myParent.loadClass(name);
- }
- }
- public LoaderToUnload(ClassLoader parent) {
- super();
- myParent = parent;
- }
- }
-
- public static void main(String... args) throws Exception {
- run();
- }
-
- private static void run() throws Exception {
- final WhiteBox wb = WhiteBox.getWhiteBox();
-
- ClassUnloadCommon.failIf(wb.isClassAlive(className), "is not expected to be alive yet");
-
- // Load interface Class with one class loader.
- ClassLoader icl = ClassUnloadCommon.newClassLoader();
- Class<?> ic = icl.loadClass(interfaceName);
-
- ClassLoader cl = new LoaderToUnload(icl);
- Class<?> c = cl.loadClass(className);
- Object o = c.newInstance();
-
- ClassUnloadCommon.failIf(!wb.isClassAlive(className), "should be live here");
- ClassUnloadCommon.failIf(!wb.isClassAlive(interfaceName), "should be live here");
-
- cl = null; c = null; o = null;
- ClassUnloadCommon.triggerUnloading();
- ClassUnloadCommon.failIf(wb.isClassAlive(className), "should have been unloaded");
- ClassUnloadCommon.failIf(!wb.isClassAlive(interfaceName), "should be live here");
- System.out.println("We still have Interface referenced" + ic);
- }
-}
-
--- a/test/hotspot/jtreg/runtime/ClassUnload/test/ImplementorClass.java Tue Oct 16 16:26:28 2018 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * 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 test;
-
-public class ImplementorClass implements Interface {
- public void foo() { System.out.println("foo implemented!"); }
-}
--- a/test/hotspot/jtreg/runtime/ClassUnload/test/Interface.java Tue Oct 16 16:26:28 2018 -0400
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-/*
- * 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 test;
-
-public interface Interface {
- public void foo();
-}
--- a/test/hotspot/jtreg/runtime/testlibrary/ClassUnloadCommon.java Tue Oct 16 16:26:28 2018 -0400
+++ b/test/hotspot/jtreg/runtime/testlibrary/ClassUnloadCommon.java Wed Oct 31 14:38:14 2018 -0400
@@ -27,10 +27,7 @@
* for an example.
*/
-
import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@@ -107,22 +104,4 @@
throw new RuntimeException(e);
}
}
-
- // Get data for pre-compiled class file to load.
- public static byte[] getClassData(String name) {
- try {
- String TempName = name.replaceAll("\\.", "/");
- String currentDir = System.getProperty("test.classes");
- String filename = currentDir + File.separator + TempName + ".class";
- System.out.println("filename is " + filename);
- 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;
- }
- }
}