Skip to content

Commit 3fa1e1d

Browse files
committed
We should mark parent class' field reachable
1 parent 4a32cdf commit 3fa1e1d

File tree

1 file changed

+16
-10
lines changed

1 file changed

+16
-10
lines changed

jvm/src/garbage_collector.rs

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use bytemuck::cast_slice;
66
use hashbrown::{HashMap, HashSet, hash_set::Entry};
77
use parking_lot::Mutex;
88

9-
use crate::{ClassInstance, JavaValue, Jvm, class_loader::Class, thread::JvmThread};
9+
use crate::{ClassDefinition, ClassInstance, Field, JavaValue, Jvm, class_loader::Class, thread::JvmThread};
1010

1111
// XXX java/util/Vector, java/util/HashMap internal..
1212
type RustVector = Arc<Mutex<Vec<Box<dyn ClassInstance>>>>;
@@ -32,18 +32,11 @@ pub fn determine_garbage(
3232
find_reachable_objects(jvm, x, &mut reachable_objects);
3333
});
3434

35-
// HACK we should test if class loader is in use
36-
for class_instance in all_class_instances.iter() {
37-
if jvm.is_instance(&**class_instance, "java/lang/ClassLoader") {
38-
find_reachable_objects(jvm, class_instance, &mut reachable_objects);
39-
}
40-
}
41-
4235
all_class_instances.difference(&reachable_objects).cloned().collect()
4336
}
4437

4538
fn find_static_reachable_objects(jvm: &Jvm, class: &Class, reachable_objects: &mut HashSet<Box<dyn ClassInstance>>) {
46-
let fields = class.definition.fields();
39+
let fields = find_all_fields(jvm, &*class.definition);
4740
for field in fields {
4841
if !field.access_flags().contains(FieldAccessFlags::STATIC) {
4942
continue;
@@ -93,7 +86,7 @@ fn find_reachable_objects(jvm: &Jvm, object: &Box<dyn ClassInstance>, reachable_
9386
}
9487
}
9588

96-
let fields = object.class_definition().fields();
89+
let fields = find_all_fields(jvm, &*object.class_definition());
9790
for field in fields {
9891
if field.access_flags().contains(FieldAccessFlags::STATIC) {
9992
continue;
@@ -111,6 +104,19 @@ fn find_reachable_objects(jvm: &Jvm, object: &Box<dyn ClassInstance>, reachable_
111104
}
112105
}
113106

107+
fn find_all_fields(jvm: &Jvm, class_definition: &dyn ClassDefinition) -> Vec<Box<dyn Field>> {
108+
let result = class_definition.fields();
109+
let super_class_name = class_definition.super_class_name();
110+
111+
if let Some(x) = super_class_name {
112+
let super_class = jvm.get_class(&x).unwrap();
113+
let super_fields = find_all_fields(jvm, &*super_class.definition);
114+
result.into_iter().chain(super_fields).collect()
115+
} else {
116+
result
117+
}
118+
}
119+
114120
// Same as Jvm's one but without async
115121
fn get_rust_object_field<T: Clone>(jvm: &Jvm, object: &dyn ClassInstance, field_name: &str) -> T {
116122
let field = jvm.find_field(&*object.class_definition(), field_name, "[B").unwrap().unwrap();

0 commit comments

Comments
 (0)